package com.yugong.util;

import jakarta.validation.constraints.NotNull;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.util.Date;

/**
 * 时间工具类
 *
 * @author yugong
 * @date 2024/2/9
 */
@Component
public class TimeUtils {
    /**
     * 将Date类型时间转成字符串类型时间
     *
     * @param date          时间
     * @param dateFormatter 时间格式
     * @return 字符串类型时间
     */
    public String setDateToStrDate(Date date, String dateFormatter) {
        if (date == null) {
            return "暂未更新";
        }
        Instant instant = date.toInstant();
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(dateFormatter);
        return zonedDateTime.format(dateTimeFormatter);
    }

    /**
     * 将字符串类型时间转成Date类型时间
     *
     * @param date          时间
     * @param dateFormatter 时间格式
     * @return Date类型时间
     */
    public Date setStrDateToDate(String date, String dateFormatter) {
        return instantToDate(
                localDateTimeToInstant(
                        stringToLocalDateTime(date, dateFormatter)));
    }

    /**
     * 将long类型时间转成Date类型时间
     *
     * @param timeMilli     long类型时间
     * @param dateFormatter 时间格式
     * @return Date类型时间
     */
    public Date longToDate(long timeMilli, String dateFormatter) {
        return setStrDateToDate(longToString(timeMilli, dateFormatter), dateFormatter);
    }

    /**
     * 将Instant类型时间转成Date类型时间
     *
     * @param instant LocalDateTime类型时间
     * @return Date类型时间
     */
    public Date instantToDate(@NotNull Instant instant) {
        return Date.from(instant);
    }

    /**
     * 将LocalDateTime类型时间转成Instant类型时间
     *
     * @param localDateTime LocalDateTime类型时间
     * @return Instant类型时间
     */
    public Instant localDateTimeToInstant(@NotNull LocalDateTime localDateTime) {
        return localDateTime
                .atZone(ZoneId.systemDefault())
                .toInstant();
    }

    /**
     * 将字符串时间转成LocalDateTime类型时间
     *
     * @param dateString    字符串时间
     * @param dateFormatter 时间格式
     * @return LocalDateTime类型时间
     */
    public LocalDateTime stringToLocalDateTime(@NotNull String dateString, String dateFormatter) {
        return LocalDateTime.parse(dateString,
                DateTimeFormatter
                        .ofPattern(dateFormatter));
    }

    /**
     * 将long类型的时间转成字符串类型的时间
     *
     * @param timeMilli     long类型的时间
     * @param dateFormatter 时间格式
     * @return 字符串类型的时间
     */
    public String longToString(long timeMilli, String dateFormatter) {
        return Instant
                .ofEpochMilli(timeMilli)
                .atZone(ZoneId.systemDefault())
                .format(DateTimeFormatter
                        .ofPattern(dateFormatter));
    }

    /**
     * 将毫秒转成百分比
     *
     * @param millis 毫秒
     * @return 百分比
     */
    public String longToPercentage(long millis) {
        long totalTimeMillis = 1000000000;
        double percent = (double) millis / totalTimeMillis * 100;
        String string = String.valueOf(percent);
        String percentage = string.substring(0, 4);
        return percentage + "%";
    }

    /**
     * 将毫秒转成时分秒
     *
     * @param millis 毫秒
     * @return 时分秒
     */
    public String longToHMS(long millis) {
        LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneId.systemDefault());
        int hours = dateTime.get(ChronoField.HOUR_OF_DAY);
        int minutes = dateTime.get(ChronoField.MINUTE_OF_HOUR);
        int seconds = dateTime.get(ChronoField.SECOND_OF_MINUTE);
        return hours + "时" + minutes + "分" + seconds + "秒";
    }
}
